﻿using AdminBase.Common.Helpers;
using AdminBase.Interface;
using AdminBase.Model;
using AdminBase.Model.Entitys;
using AutoMapper;
using SqlSugar;

namespace AdminBase.Service
{
    /// <summary>
    /// 权限业务实现类
    /// </summary>
    public class PermissionsService : IPermissionsService
    {
        private readonly IMapper _mapper;
        private ISqlSugarClient _db { get; set; }

        /// <summary>
        /// 构造注入
        /// </summary>
        /// <param name="mapper"></param>
        /// <param name="db"></param>
        public PermissionsService(IMapper mapper, ISqlSugarClient db)
        {
            _mapper = mapper;
            _db = db;
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="permission"></param>
        /// <returns></returns>
        public bool Add(Permissions permission)
        {
            EntityHelper.SetAddValues(permission);
            return _db.Insertable(permission).ExecuteCommand() > 0;
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="permission"></param>
        /// <returns></returns>
        public bool Edit(Permissions entity)
        {
            var oEntity = _db.Queryable<Permissions>().First(p => p.ID == entity.ID);
            oEntity = _mapper.Map(entity, oEntity);
            oEntity = EntityHelper.SetEditValues(oEntity);
            return _db.Updateable(oEntity).ExecuteCommand() > 0;
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool Del(long id)
        {
            List<long> ids = new List<long>() { id };
            return DeletePermissionAndChildren(ids);
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="idList"></param>
        /// <returns></returns>
        public bool BatchDel(List<long> idList)
        {
            if (idList.Any())
            {
                return DeletePermissionAndChildren(idList);
            }
            return false;
        }

        /// <summary>
        /// 删除权限及其子级权限
        /// </summary>
        /// <param name="pids">权限ID</param>
        private bool DeletePermissionAndChildren(List<long> pids)
        {
            List<long> ids = new List<long>();
            GetChildrenIDs(pids, ref ids);
            return _db.Deleteable<Permissions>().In(ids).ExecuteCommand() > 0;
        }

        /// <summary>
        /// 根据ID获取子级ID列表
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        private void GetChildrenIDs(List<long> pids, ref List<long> ids)
        {
            ids.AddRange(pids);
            // 获取所有子级ID
            var childIds = _db.Queryable<Permissions>()
                               .Where(p => p.ParentID != null && pids.Contains(p.ParentID.Value))
                               .Select(p => p.ID)
                               .ToList();
            if (childIds.Any())
            {
                // 递归获取子级
                GetChildrenIDs(childIds, ref ids);
            }
        }

        /// <summary>
        /// 获取单个
        /// </summary>
        /// <returns></returns>
        public PermissionsDto GetPermission(long id)
        {
            var info = _db.Queryable<Permissions>().First(p => p.ID == id);
            return _mapper.Map<PermissionsDto>(info);
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="queryParam">查询参数</param>
        /// <returns></returns>
        public PageInfo GetPermissions(PermissionsQueryParam queryParam)
        {
            PageInfo pageInfo = new PageInfo();
            var exp = _db.Queryable<Permissions>()
                .WhereIF(!string.IsNullOrWhiteSpace(queryParam.KeyWord), p =>
                    p.Sign != null && p.Sign.Contains(queryParam.KeyWord) ||
                    p.Name != null && p.Name.Contains(queryParam.KeyWord) ||
                    p.Path != null && p.Path.Contains(queryParam.KeyWord) ||
                    p.Description != null && p.Description.Contains(queryParam.KeyWord))
                .OrderBy(u => u.Sort == null ? int.MaxValue : u.Sort)
                .Select(u => new PermissionsDto
                {
                    ID = u.ID,
                    Sign = u.Sign,
                    Name = u.Name,
                    IsMenu = u.IsMenu,
                    Method = u.Method,
                    Path = u.Path,
                    ParentID = u.ParentID,
                    Icon = u.Icon,
                    Sort = u.Sort,
                    Description = u.Description,
                    IsDeleted = u.IsDeleted,
                    CreateUserName = u.CreateUserName,
                    CreateDateTime = u.CreateDateTime,
                    UpdateUserName = u.UpdateUserName,
                    UpdateDateTime = u.UpdateDateTime
                }).ToList();

            exp = GetTreeMenus(exp);
            // 分页取出
            var res = exp
                .Skip((queryParam.PageIndex - 1) * queryParam.PageSize)
                .Take(queryParam.PageSize)
                .ToList();
            pageInfo.Data = res;
            pageInfo.Count = exp.Count();
            return pageInfo;
        }

        /// <summary>
        /// 根据用户ID获取权限ids
        /// </summary>
        /// <param name="userID">用户ID</param>
        /// <returns></returns>
        public List<long> GetPermissionsIDsByUserID(long userID)
        {
            List<long> ids = new List<long>();
            var list = GetPermissionsByUserID(userID);
            if (list.Any())
            {
                ids = list.Select(p => p.ID).ToList();
            }
            return ids;
        }

        /// <summary>
        /// 根据用户ID获取权限
        /// </summary>
        /// <param name="userID">用户ID</param>
        /// <returns></returns>
        public List<PermissionsDto> GetPermissionsByUserID(long userID)
        {
            var roleIDs = _db.Queryable<UsersRoles>().Where(u => u.UserID == userID).Select(u => u.RoleID).ToList();
            var permissionIDs = _db.Queryable<RolesPermissions>().Where(p => roleIDs.Contains(p.RoleID)).Select(p => p.PermissionID).ToList();
            var permissions = _db.Queryable<Permissions>().In(permissionIDs)
                .Select(p => new PermissionsDto
                {
                    ID = p.ID,
                    Sign = p.Sign
                })
                .ToList();
            return permissions;
        }

        /// <summary>
        /// 获取所有权限的树形数据
        /// </summary>
        /// <returns></returns>
        public List<TreeDto> GetTreeData()
        {
            var list = _db.Queryable<Permissions>()
                .OrderBy(p => p.Sort)
                .Select(u => new TreeBase
                {
                    ID = u.ID,
                    Name = u.Name,
                    ParentID = u.ParentID,
                }).ToList();
            return TreeDataHelper.GetTreeData(list);
        }

        /// <summary>
        /// 根据用户获取菜单权限（树列表）
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        public List<PermissionsDto> GetMenus()
        {
            var list = _db.Queryable<Permissions>()
                .Where(p => p.IsMenu == true)
                .OrderBy(p => p.Sort)
                .Select(u => new PermissionsDto
                {
                    ID = u.ID,
                    Sign = u.Sign,
                    Name = u.Name,
                    Icon = u.Icon,
                    ParentID = u.ParentID,
                }).ToList();
            return GetTreeMenus(list);
        }

        /// <summary>
        /// 获取菜单树
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private static List<PermissionsDto> GetTreeMenus(List<PermissionsDto> list)
        {
            // 从一级菜单开始往下找子级菜单
            List<PermissionsDto> newlist = list.Where(p => p.ParentID == 0 || p.ParentID == null).ToList();
            //通过递归获取子级
            GetChildren(list, newlist);
            return newlist.Distinct(new DisComparer<PermissionsDto>("Name")).ToList();
        }

        /// <summary>
        /// 递归获取子菜单
        /// </summary>
        /// <param name="all"></param>
        /// <param name="res"></param>
        private static void GetChildren(List<PermissionsDto> all, List<PermissionsDto> res)
        {
            if (res != null && res.Count > 0)
            {
                res.ForEach(item =>
                {
                    var child = all.Where(p => p.ParentID == item.ID).Distinct(new DisComparer<PermissionsDto>("Name")).OrderBy(p => p.Sort).ToList();
                    if (child != null && child.Count > 0)
                    {
                        item.Children = child;
                        GetChildren(all, child);
                    }
                });
            }
        }

        /// <summary>
        /// 获取权限方法
        /// </summary>
        /// <returns></returns>
        public List<ValueLabel> GetPermissionMethods()
        {
            var list = new List<ValueLabel>();
            var enumList = EnumHelper.GetEnumValuesDescriptions<MethodChoices>();
            foreach (var kv in enumList)
            {
                list.Add(new ValueLabel()
                {
                    Value = kv.Key,
                    Label = kv.Value,
                });
            }
            return list;
        }
    }
}
